package com.ruslan.magaz.web;


import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.ruslan.magaz.domain.Category;
import com.ruslan.magaz.domain.Order;
import com.ruslan.magaz.domain.OrderStatus;
import com.ruslan.magaz.domain.OrderStatusName;
import com.ruslan.magaz.domain.Product;
import com.ruslan.magaz.domain.User;
import com.ruslan.magaz.service.ItemService;
import com.ruslan.magaz.service.OrderService;
import com.ruslan.magaz.service.UserService;

@Controller
@RequestMapping("/admin/order")
public class AdminOrder {
	private static final int ORDER_PAGE_SIZE = 15;
	private static final int ITEMS_PAGE_SIZE = 15;

	@Autowired
	private UserService userService;
	
	@Autowired
	private ItemService itemService;
	
	@Autowired
	private OrderService orderService;
	
	@ModelAttribute("users")
	 public List<User> getAllUsers() {
	  return userService.getAllUsersNotAdmin();
	}
	
	@InitBinder
    public void initBinder(WebDataBinder binder) {
        SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy HH:mm");
        sdf.setLenient(true);
        binder.registerCustomEditor(Date.class, new CustomDateEditor(sdf, true));
    }
	
	Map<Integer, String> formStatusMap(List<OrderStatusName> osnList){
		Map<Integer, String> rMap = new TreeMap<Integer, String>(); 
		for (OrderStatusName osn: osnList){
			rMap.put(osn.getOrderStatusNameId(), osn.getName());
		}
		return rMap;
	}
	
	@RequestMapping(value="")
    public String adminProducts(HttpServletRequest req, HttpServletResponse res, @RequestParam(required = false) Integer userId, @RequestParam(required = false) Integer pageNum, Model model) throws ServletException, IOException{
		if (userId == null){
			userId=userService.getFirstUserId();
		}
        if (pageNum == null){
			pageNum=1;
		}
        
//		List<Order> orders = orderService.getAllOrdersForUser(userId);
		List rawOrderLines = orderService.getOrderLines(userId, pageNum, ORDER_PAGE_SIZE);
		List<OrderLine> orderLines = OrderLine.getOrderLines(rawOrderLines); 
		model.addAttribute("orderLines", orderLines);
		model.addAttribute("lastPageNum", orderService.ordersForUserPageCount(userId, ORDER_PAGE_SIZE));
		model.addAttribute("userId", userId);
        return "adminTiles/adminOrders";
	 }
	
	
	@RequestMapping(value="/status")
    public String editProduct(HttpServletRequest req, HttpServletResponse res, @RequestParam Integer orderId, @RequestParam(required = false) Integer pageNum, Model model) throws ServletException, IOException{
	        
	        List<OrderStatus> orderStatuses = orderService.getOrderStatusesForOrder(orderId);
			model.addAttribute("orderStatuses", orderStatuses);
			model.addAttribute("orderId", orderId);
		    return "adminTiles/adminOrderStatuses";
	}
	
	@RequestMapping(value="/status/edit", method=RequestMethod.GET)
    public String editStatus(HttpServletRequest req, HttpServletResponse res, @RequestParam Integer orderStatusId, Model model) throws ServletException, IOException{
		List<OrderStatusName> sNames = orderService.getAllOrderStatusNames();
		Map< Integer, String > statuses =  formStatusMap(sNames);
		OrderStatus orderStatus = orderService.getOrderStatusById(orderStatusId);
		model.addAttribute("statuses", statuses);
		model.addAttribute("orderStatus", orderStatus);
		model.addAttribute("add", false);
	    return "adminTiles/adminEditOrderStatus";
	}
	
	@RequestMapping(value="/status/edit", method=RequestMethod.POST)
    public String editStatusPost(HttpServletRequest req, HttpServletResponse res, Model model, @Valid @ModelAttribute OrderStatus orderStatus, BindingResult bindingResult) throws ServletException, IOException{
		if(bindingResult.hasErrors()){
			List<OrderStatusName> sNames = orderService.getAllOrderStatusNames();
			Map< Integer, String > statuses =  formStatusMap(sNames);
			model.addAttribute("statuses", statuses);
			 return "adminTiles/adminEditOrderStatus";
		 }
		List<OrderStatus> orderStatuses = orderService.getOrderStatusesForOrder(orderStatus.getOrder().getOrderId());
		for (OrderStatus os: orderStatuses){
			if (orderStatus.getOrderStatusName().getOrderStatusNameId() == os.getOrderStatusName().getOrderStatusNameId() && orderStatus.getOrderStatusId() != os.getOrderStatusId()){
				model.addAttribute("statusExists", true);
				List<OrderStatusName> sNames = orderService.getAllOrderStatusNames();
				Map< Integer, String > statuses =  formStatusMap(sNames);
				model.addAttribute("statuses", statuses);
				return "adminTiles/adminEditOrderStatus";
			}
		}
		
		orderService.editOrderStatus(orderStatus);
	    return "redirect:/admin/order/status?orderId="+orderStatus.getOrder().getOrderId();
	}
	
	@RequestMapping(value="/status/add", method=RequestMethod.GET)
    public String addStatus(HttpServletRequest req, HttpServletResponse res, @RequestParam Integer orderId, Model model) throws ServletException, IOException{
		List<OrderStatusName> sNames = orderService.getAllOrderStatusNames();
		Map< Integer, String > statuses =  formStatusMap(sNames);
		OrderStatus orderStatus = new OrderStatus();
		Order order = orderService.getOrderById(orderId);
		orderStatus.setOrder(order);
		
 		model.addAttribute("add", true);
 		model.addAttribute("statuses", statuses);
 		model.addAttribute("orderStatus", orderStatus);
        return "adminTiles/adminEditOrderStatus";
        
        
	 }
	
	@RequestMapping(value="/status/add", method=RequestMethod.POST)
    public String addStatusPost(HttpServletRequest req, HttpServletResponse res, Model model, @Valid @ModelAttribute OrderStatus orderStatus, BindingResult bindingResult) throws ServletException, IOException{
		if(bindingResult.hasErrors()){
			List<OrderStatusName> sNames = orderService.getAllOrderStatusNames();
			Map< Integer, String > statuses =  formStatusMap(sNames);
			model.addAttribute("statuses", statuses);
			return "adminTiles/adminEditOrderStatus";
		 }
		List<OrderStatus> orderStatuses = orderService.getOrderStatusesForOrder(orderStatus.getOrder().getOrderId());
		for (OrderStatus os: orderStatuses){
			if (orderStatus.getOrderStatusName().getOrderStatusNameId() == os.getOrderStatusName().getOrderStatusNameId()){
				model.addAttribute("statusExists", true);
				List<OrderStatusName> sNames = orderService.getAllOrderStatusNames();
				Map< Integer, String > statuses =  formStatusMap(sNames);
				model.addAttribute("statuses", statuses);
				return "adminTiles/adminEditOrderStatus";
			}
		}
		orderService.addOrderStatus(orderStatus.getOrder().getOrderId(), orderStatus);
	    return "redirect:/admin/order/status?orderId="+orderStatus.getOrder().getOrderId();
	}
	
	@RequestMapping(value="/status/remove")
    public String removeStatus(HttpServletRequest req, HttpServletResponse res, @RequestParam Integer orderStatusId, RedirectAttributes redir) throws ServletException, IOException{
			OrderStatus orderStatus = orderService.getOrderStatusById(orderStatusId);
	 		orderService.removeOrderStatus(orderStatus);
	        return "redirect:/admin/order/status?orderId="+orderStatus.getOrder().getOrderId();
	 }
	
}
